#include <iostream>
#include <pthread.h> //原生线程库
#include <unistd.h>
#include <thread>
using namespace std;

// 如果多线程访问同一个全局变量，并对它进行数据计算，多线程会相互影响吗？
// 在并发访问的时候导致了我们数据不一致
int tickets = 10000;// 未来的临界资源，现在还不能保证任意时刻只允许一个执行流访问

void *getTickets(void *args)
{
    (void)args;
    while (true)
    {
        if (tickets > 0) // 临界区
        {
            usleep(1000);
            printf("%p : %d\n",pthread_self(),tickets);
            tickets--;
        }
        else
        {
            break;
        }
    }
    return nullptr;
}

int main()
{
    pthread_t t1, t2, t3;
    // 多线程抢票的逻辑
    pthread_create(&t1, nullptr, getTickets, nullptr);
    pthread_create(&t2, nullptr, getTickets, nullptr);
    pthread_create(&t3, nullptr, getTickets, nullptr);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);

    return 0;
}

// 这些用的都是原生线程库
// // 1.线程谁先运行与调度器有关
// // 2.线程一旦异常，可能导致整个进程退出
// // 3.线程的输入和返回值问题
// // 4.线程异常退出的理解 - 不用接收返回值，因为线程出异常整个进程就都崩溃了
// void* pthreadRoutine(void* args)
// {
//     // pthread_cancel(pthread_self); // 不推荐
//     int i = 0;
//     int* data = new int[10];
//     while(true)
//     {
//         cout << "新线程：" << (char*)args << "running...." << pthread_self() << endl;
//         sleep(1);
//         // data[i] = i;
//         // int a = 10;
//         // a = a/0;
//         // if(i++ == 10) break;
//     }
//     cout << "new thread quit\n";
//     return (void*)data;
// }

// int main()
// {
//     pthread_t tid; // 本质是一个地址
//     pthread_create(&tid,nullptr,pthreadRoutine,(void*)"thread 1");
//     // pthread_join(tid,nullptr);// 默认阻塞等待
//     printf("%lu,%p\n",tid,tid);
//     int i = 0;
//     while(true)
//     {
//         cout << "主进程：" << "running...." << endl;
//         sleep(1);
//         if(i++ == 5) break;
//     }
//     // 1.线程被取消，join的时候，退出码是-1 #define PTHREAD_CANCELED ((void *) -1)
//     // PTHREAD_CANCELED
//     pthread_cancel(tid);
//     cout << "pthread cancel,tid:" << tid << endl;
//     int* ret = nullptr;
//     pthread_join(tid,(void**)&ret);

//     cout << "main thread wait done ... main quit  exit code:" << (long long)ret << endl;
//     // for(int i = 0;i < 10;i++)
//     // {
//     //     cout << ret[i] << endl;
//     // }
//     // 3.线程在创建并执行时，也是需要被主线程等待的，如果不进行等待，会造成类似进程的僵尸问题，造成内存泄漏
//     // while(true)
//     // {
//     //     cout << "主进程：" << "running...." << endl;
//     //     sleep(1);
//     // }

//     return 0;
// }